/*
 * SHANGHAI SUNNY EDUCATION, INC. CONFIDENTIAL
 *
 * Copyright 2011-2016 Shanghai Sunny Education, Inc. All Rights Reserved.
 *
 * NOTICE: All information contained herein is, and remains the property of
 * Shanghai Sunny Education, Inc. and its suppliers, if any. The intellectual
 * and technical concepts contained herein are proprietary to Shanghai Sunny
 * Education, Inc. and its suppliers and may be covered by patents, patents
 * in process, and are protected by trade secret or copyright law. Dissemination
 * of this information or reproduction of this material is strictly forbidden
 * unless prior written permission is obtained from Shanghai Sunny Education, Inc.
 */

package com.duobao.util;

import com.fasterxml.jackson.annotation.JsonIgnore;

import java.text.MessageFormat;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * Map based message for controller.
 *
 * @author haitian.gan
 * @serial
 * @since 2017-03-08 13:18
 */
public class MapMessage extends LinkedHashMap<String, Object> {
    private static final long serialVersionUID = -5410799397055048515L;

    private static final String __duplicatedOperation = "__duplicatedOperation";

    // ========================================================================
    // success
    // ========================================================================

    public MapMessage setSuccess(Boolean v) {
        put("success", v);
        return this;
    }

    @JsonIgnore
    public boolean isSuccess() {
        Object value = get("success");
        if (value == null) {
            return false;
        }
        if (value instanceof Boolean) {
            return (Boolean) value;
        }
        return (value instanceof String) && ("true".equals(value));
    }

    /**
     * 仅用于兼容之前的 Message 对象的代码
     *
     * @return {@link #isSuccess()}
     */
    @JsonIgnore
    @Deprecated
    public boolean getSuccess() {
        return isSuccess();
    }

    // ========================================================================
    // info
    // ========================================================================

    @JsonIgnore
    public MapMessage setInfo(String s) {
        put("info", s);
        return this;
    }

    @JsonIgnore
    public String getInfo() {
        Object value = get("info");
        if (value == null) {
            return "";
        }
        if (!(value instanceof String)) {
            return "";
        }
        return (String) value;
    }

    // ========================================================================
    // errorUrl and errorCode
    // ========================================================================

    public MapMessage setErrorUrl(String s) {
        put("errorUrl", s);
        return this;
    }

    @JsonIgnore
    public String getErrorUrl() {
        Object value = get("errorUrl");
        if (value == null) {
            return "";
        }
        if (!(value instanceof String)) {
            return "";
        }
        return (String) value;
    }

    public void clearErrorUrl() {
        remove("errorUrl");
    }

    public MapMessage setErrorCode(String s) {
        put("errorCode", s);
        return this;
    }

    @JsonIgnore
    public String getErrorCode() {
        Object value = get("errorCode");
        if (value == null) {
            return "";
        }
        if (!(value instanceof String)) {
            return "";
        }
        return (String) value;
    }

    public void clearErrorCode() {
        remove("errorCode");
    }

    // ========================================================================
    // value
    // ========================================================================

    @Deprecated
    public MapMessage setValue(Object v) {
        put("value", v);
        return this;
    }

    @JsonIgnore
    @Deprecated
    public Object getValue() {
        return get("value");
    }

    // ========================================================================
    // attributes
    // ========================================================================

    /**
     * 仅用于兼容之前的 Message 对象的代码
     *
     * @return return 'attributes' as map.
     */
    @JsonIgnore
    @Deprecated
    public Map getAttributes() {
        Map m = (Map) get("attributes");
        if (m == null) {
            m = new LinkedHashMap();
            put("attributes", m);
        }
        return m;
    }

    /**
     * 仅用于兼容之前的 Message 对象的代码
     *
     * @param m put specified map with 'attributes' key
     */
    @Deprecated
    public void setAttributes(Map m) {
        put("attributes", m);
    }

    // ========================================================================
    // duplicatedException
    // ========================================================================

    public MapMessage withDuplicatedException() {
        return add(__duplicatedOperation, Boolean.TRUE);
    }

    @JsonIgnore
    public boolean hasDuplicatedException() {
        return containsKey(__duplicatedOperation);
    }


    // ========================================================================
    // add & set
    // ========================================================================

    public MapMessage add(String k, Object v) {
        Object last = super.put(k, v);
        if (last != null) {
            throw new IllegalArgumentException("key " + k + " already exists in map, overwritten by new value");
        }
        return this;
    }

    public MapMessage set(String k, Object v) {
        super.put(k, v);
        return this;
    }

    // ========================================================================
    // static factory methods
    // ========================================================================

    public static MapMessage of(Map<String, Object> map) {
        if (map == null) {
            return null;
        }
        MapMessage message = new MapMessage();
        message.putAll(map);
        return message;
    }

    public static MapMessage successMessage() {
        return new MapMessage().setSuccess(true);
    }

    /*public static MapMessage successMessage(String info, Object... args) {
        info = StringUtils.formatMessage(info, args);
        return new MapMessage().setSuccess(true).setInfo(info);
    }*/

    public static MapMessage errorMessage() {
        return new MapMessage().setSuccess(false);
    }

    public static MapMessage errorMessage(String info, Object... args) {
        info = MessageFormat.format(info, args);
        return new MapMessage().setSuccess(false).setInfo(info);
    }
}
